using System;
using UnityEngine;
using Random = UnityEngine.Random;

namespace FrameWork.Weather
{
    

    /// <summary>
    /// 基于马尔可夫链的天气系统
    /// </summary>
    public class MarkovWeatherSystem : MonoBehaviour
    {
        
        // 当前天气状态
        private WeatherState currentState;

        // 各季节的天气状态转移概率矩阵
        private float[,] springTransitionMatrix = new float[,]
        {
            // 今天天气->明天天气概率:
            // 下雨，下雪，晴天，阴天，雷阵雨，刮风，冰雹
            { 0.25f, 0.0f, 0.15f, 0.25f, 0.15f, 0.1f, 0.1f },         // 下雨
            { 0.1f, 0.0f, 0.5f, 0.1f, 0.1f, 0.1f, 0.1f },             // 春天不下雪，设置概率出口，防止冬天最后一天是下雪
            { 0.15f, 0.0f, 0.25f, 0.2f, 0.15f, 0.15f, 0.1f },         // 晴天
            { 0.3f, 0.0f, 0.15f, 0.25f, 0.1f, 0.1f, 0.1f },           // 阴天
            { 0.3f, 0.0f, 0.1f, 0.2f, 0.2f, 0.1f, 0.1f },             // 雷阵雨
            { 0.2f, 0.0f, 0.1f, 0.25f, 0.15f, 0.2f, 0.1f },           // 刮风
            { 0.3f, 0.0f, 0.1f, 0.2f, 0.15f, 0.15f, 0.1f }            // 冰雹
        };

        private float[,] summerTransitionMatrix = new float[,]
        {
            // 今天天气->明天天气概率: 
            // 下雨，下雪，晴天，阴天，雷阵雨，刮风，冰雹
            { 0.2f, 0.0f, 0.1f, 0.2f, 0.3f, 0.1f, 0.1f },             // 下雨
            { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },             // 夏天不下雪
            { 0.1f, 0.0f, 0.5f, 0.1f, 0.1f, 0.1f, 0.1f },             // 晴天
            { 0.2f, 0.0f, 0.4f, 0.15f, 0.1f, 0.05f, 0.1f },           // 阴天
            { 0.3f, 0.0f, 0.2f, 0.15f, 0.2f, 0.05f, 0.1f },           // 雷阵雨
            { 0.1f, 0.0f, 0.3f, 0.25f, 0.15f, 0.1f, 0.1f },           // 刮风
            { 0.3f, 0.0f, 0.2f, 0.2f, 0.15f, 0.05f, 0.1f }            // 冰雹
        };

        private float[,] autumnTransitionMatrix = new float[,]
        {
            // 今天天气->明天天气概率: 
            // 下雨，下雪，晴天，阴天，雷阵雨，刮风，冰雹
            { 0.25f, 0.0f, 0.15f, 0.15f, 0.25f, 0.1f, 0.1f },         // 下雨
            { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },             // 秋天不下雪
            { 0.15f, 0.0f, 0.35f, 0.1f, 0.15f, 0.15f, 0.1f },         // 晴天
            { 0.3f, 0.0f, 0.25f, 0.15f, 0.1f, 0.1f, 0.1f },           // 阴天
            { 0.3f, 0.0f, 0.15f, 0.15f, 0.2f, 0.1f, 0.1f },           // 雷阵雨
            { 0.2f, 0.0f, 0.15f, 0.1f, 0.15f, 0.2f, 0.1f },           // 刮风
            { 0.3f, 0.0f, 0.15f, 0.15f, 0.15f, 0.15f, 0.1f }          // 冰雹
        };

        private float[,] winterTransitionMatrix = new float[,]
        {
            // 当前天气->下一天气概率: 
            // 下雨，下雪，晴天，阴天，雷阵雨，刮风，冰雹
            { 0.0f, 0.4f, 0.1f, 0.3f, 0.0f, 0.2f, 0.0f },             // 冬天不下雨
            { 0.0f, 0.5f, 0.2f, 0.2f, 0.0f, 0.1f, 0.0f },             // 下雪，概率最高
            { 0.0f, 0.3f, 0.3f, 0.3f, 0.0f, 0.1f, 0.0f },             // 晴天
            { 0.0f, 0.3f, 0.2f, 0.4f, 0.0f, 0.1f, 0.0f },             // 阴天，概率其次
            { 0.1f, 0.3f, 0.1f, 0.3f, 0.0f, 0.2f, 0.0f },             // 雷阵雨，冬天不下雨
            { 0.0f, 0.3f, 0.1f, 0.3f, 0.0f, 0.3f, 0.0f },             // 刮风，概率其次
            { 0.1f, 0.6f, 0.1f, 0.1f, 0.0f, 0.1f, 0.0f }              // 冬天不下冰雹，设置概率出口，防止秋天最后一天是冰雹
        };

        private void Start()
        {
            InitializeWeather();
            // 事件注册，由时间系统驱动，新的一天来临，更新天气
            EventSystem.Instance.AddListener<Season>(EventName.EVENT_TIME_WEATHER_UPDATE, UpdateWeather);
        }

        // 初始化天气状态
        private void InitializeWeather()
        {
            // 第一天是晴天
            currentState = WeatherState.Sunny;
            // Debug.Log("初始化天气 " + currentState);
            SceneWeatherManager.Instance.ApplyWeatherEffects(currentState);
        }

        // 更新天气状态
        private void UpdateWeather(Season currentSeason)
        {
            // 根据当前天气状态和季节，计算下一个天气状态
            currentState = GetNextState(currentState, currentSeason);
            // Debug.Log("天气变更为 " + currentState);
            SceneWeatherManager.Instance.ApplyWeatherEffects(currentState);
        }

        // 根据当前状态和季节获取下一个状态
        private WeatherState GetNextState(WeatherState currentState, Season currentSeason)
        {
            int currentIndex = (int)currentState;
            float randomValue = Random.value;
            float cumulativeProbability = 0f;

            float[,] transitionMatrix = GetSeasonalTransitionMatrix(currentSeason);

            for (int nextStateIndex = 0;
                 nextStateIndex < Enum.GetValues(typeof(WeatherState)).Length;
                 nextStateIndex++)
            {
                cumulativeProbability += transitionMatrix[currentIndex, nextStateIndex];
                if (randomValue <= cumulativeProbability)
                {
                    // 检查是否在非冬季出现下雪
                    if (nextStateIndex == (int)WeatherState.Snowy && currentSeason != Season.冬)
                    {
                        // 如果在非冬季出现下雪，重新计算
                        return GetNextState(currentState, currentSeason);
                    }

                    return (WeatherState)nextStateIndex;
                }
            }

            // 默认返回当前状态（防止概率计算错误）
            return currentState;
        }

        // 根据季节获取对应的转移矩阵
        private float[,] GetSeasonalTransitionMatrix(Season currentSeason)
        {
            switch (currentSeason)
            {
                case Season.春:
                    return springTransitionMatrix;
                case Season.夏:
                    return summerTransitionMatrix;
                case Season.秋:
                    return autumnTransitionMatrix;
                case Season.冬:
                    return winterTransitionMatrix;
                default:
                    return springTransitionMatrix; // 默认返回春季矩阵
            }
        }
    }
}